﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MailSender.Utils;
using System.Net.Mail;
using MailSender.Properties;
using System.Net;

namespace MailSender
{
	public partial class MainForm : Form
	{
		MailRtns mailRtns = null;


		public MainForm()
		{
			InitializeComponent();
            
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

			this.compressAttachementsToolStripMenuItem.Checked = UserData.Current.mail_compress;
			this.oneMailPerRecipientToolStripMenuItem.Checked = UserData.Current.one_mail_per_recipient;
		}

		protected override void OnClosing(CancelEventArgs e)
		{
			Utils.UserData.Current.Save();
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="files"></param>
		/// <param name="recipients"></param>
		/// <param name="mailIdx">Poradove cislo mailu do hlavicky</param>
		/// <returns></returns>
		private IEnumerable<MailMessage> PrepareMailMessage(List<FileInfoEx> files, MailAddress[] recipients)
		{
			List<MailAddress[]> recipientsList = new List<MailAddress[]>();
			if (Utils.UserData.Current.one_mail_per_recipient)
			{
				foreach (MailAddress ma in recipients)
					recipientsList.Add(new MailAddress[] { ma });
			}
			else
				recipientsList.Add(recipients);

			List<MailMessage> mmList = new List<MailMessage>();
			foreach (MailAddress[] maArray in recipientsList)
			{
				MailMessage mm = new MailMessage();
				mm.From = new MailAddress(UserData.Current.mail_username);
				mm.Subject = this.tbSubject.Text;
				mm.Body = this.tbMessage.Text;
				mm.IsBodyHtml = false;

				foreach (MailAddress ma in maArray)
					mm.To.Add(ma);

				foreach (FileInfoEx fie in files)
					mm.Attachments.Add(new Attachment(fie.FullFileName));

				mmList.Add(mm);
			}

			return mmList;
		}

		#region SetStatusText

		delegate void SetStatusTextDelegate(string text);

		private void SetStatusText(string text)
		{
			if (this.statusStrip1.InvokeRequired)
				this.statusStrip1.Invoke(new SetStatusTextDelegate(SetStatusText), text);
			else
				this.lblStatus.Text = text;
		}

		#endregion

		#region GUI Event Handlers

		private void senderSettingsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Forms.SenderSettings ss = new Forms.SenderSettings();
			DialogResult result = ss.ShowDialog();
		}

		private void compressAttachementsToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
		{
			UserData.Current.mail_compress = ((ToolStripMenuItem)sender).Checked;
		}

		private void listBox1_DragEnter(object sender, DragEventArgs e)
		{
			if (e.Data.GetDataPresent(DataFormats.FileDrop))
				e.Effect = DragDropEffects.Copy;
			else
				e.Effect = DragDropEffects.None;
		}

		private void listBox1_DragDrop(object sender, DragEventArgs e)
		{
			// Extract the data from the DataObject-Container into a string list
			string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);

			// Do something with the data...
			long sumSize = 0;

			// For example add all files into a simple label control:
			foreach (string file in FileList)
			{
				FileInfoEx fie = new FileInfoEx(file);
				//if (fie.Size > UserData.Current.MaxSize)
				//{

				this.lbFileNames.Items.Add(fie);

				sumSize += fie.Size;
				this.lblStatus.Text = string.Format("Files size: {0}", FileInfoEx.GetReadableFileSize(sumSize));
			}
		}

		private void btnSend_Click(object sender, EventArgs e)
		{
			SetStatusText("Preparing data...");

			if (string.IsNullOrWhiteSpace(this.tbSubject.Text))
			{
				if (MessageBox.Show(Resources.warning_no_subject, Resources.warning, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.No)
					return;
			}

			if (string.IsNullOrWhiteSpace(this.tbRecipients.Text))
			{
				MessageBox.Show(Resources.warning_no_recipient, Resources.warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				return;
			}

			Cursor.Current = Cursors.WaitCursor;

			mailRtns = new MailRtns();
			mailRtns.OnMailSent += new MailRtns.OnMailSentDelegate(mailRtns_OnMailSent);

			List<MailAddress> recipientsMailAddresses = new List<MailAddress>();
			string[] recipients = this.tbRecipients.Text.Split(',',';');
			foreach (string recipient in recipients)
			{
				string r = recipient.Trim();

				if (string.IsNullOrEmpty(r))
					continue;

				string strAddress = r;
				string displayName = r;
				int idx = r.IndexOf('<') + 1;
				int len = r.IndexOf('>') - idx;
				if (idx > 0)
					strAddress = r.Substring(idx, len);

				if (r.Contains('"'))
				{
					idx = r.IndexOf('"') + 1;
					len = r.IndexOf('"', idx) - idx;
					displayName = r.Substring(idx, len);
				}

				if (!string.IsNullOrEmpty(displayName))
					recipientsMailAddresses.Add(new MailAddress(strAddress, displayName));
				else
					recipientsMailAddresses.Add(new MailAddress(strAddress));
			}

			List<MailMessage> mailMessages = new List<MailMessage>();
			List<FileInfoEx> filesToSend = new List<FileInfoEx>();
			long sizeSum = 0;
			int mailCountUnique = 0;

			for (int i = 0; i < this.lbFileNames.Items.Count; i++)
			{
				FileInfoEx currentFile = this.lbFileNames.Items[i] as FileInfoEx;
				if (sizeSum + currentFile.Size > UserData.Current.MaxSize)
				{
					mailMessages.AddRange(PrepareMailMessage(filesToSend, recipientsMailAddresses.ToArray()));
					filesToSend = new List<FileInfoEx>();
					sizeSum = 0;
					mailCountUnique++;
				}

				sizeSum += currentFile.Size;
				filesToSend.Add(currentFile);
			}

			if (sizeSum > 0)
			{
				mailMessages.AddRange(PrepareMailMessage(filesToSend, recipientsMailAddresses.ToArray()));
				mailCountUnique++;
			}

			SetStatusText("Starting send mails: 1/" + mailMessages.Count);
			mailRtns.MailCountUnuque = mailCountUnique;
			mailRtns.SendMailStart(mailMessages);
		}

		void mailRtns_OnMailSent(int mailCount, int mailSent)
		{
			SetStatusText(string.Format("{0}/{1}", mailSent, mailCount));
			if (mailSent == mailCount)
				Cursor.Current = Cursors.Default;
		}

		private void lbFileNames_KeyDown(object sender, KeyEventArgs e)
		{
			switch (e.KeyCode)
			{
				case Keys.Delete:
					if (this.lbFileNames.SelectedItems.Count > 0)
					{
						while(this.lbFileNames.SelectedItems.Count>0)
							this.lbFileNames.Items.Remove(this.lbFileNames.SelectedItems[0] as FileInfoEx);
					}
					break;
			}
		}

		private void oneMailPerRecipientToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Utils.UserData.Current.one_mail_per_recipient = ((ToolStripMenuItem)sender).Checked;
		}

		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		#endregion
	}
}
